<?php
declare(strict_types=1);
/**
 * Notes:
 * User: ysian
 * Time: 21:46
 * @return
 */

namespace Ysian\Storage\adapter;

use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use Throwable;
use Ysian\Storage\exception\StorageException;

class QiniuAdapter extends AdapterAbstract
{
    use FileInfo;

    protected $instance = null;
    protected $uploadToken = null;

    /**
     * @return UploadManager|null
     */
    public function getInstance(): ?UploadManager
    {
        if (!$this->instance) {
            $this->instance = new UploadManager();
        }
        return $this->instance;
    }

    /**
     * @ 上传令牌
     * @return string
     */
    public function getUploadToken(): string
    {
        if (!$this->uploadToken) {
            $auth = new Auth($this->config['accessKey'], $this->config['secretKey']);
            $this->uploadToken = $auth->uploadToken($this->config['bucket']);
        }
        return $this->uploadToken;
    }

    /**
     * 上传文件
     * @param array $options
     * @return array
     */
    public function uploadFile(array $options = []): array
    {
        try {
            $result   = []; //返回数据
            $saveData = []; //需保存的数据
            $dirname  = $this->config['dirname'];
            foreach ($this->files as $key => $file) {
                $fileInfo = $this->fileInfo($file);
                $this->checkFile($fileInfo->extention);
                $md5      = hash_file('md5', $fileInfo->pathName);
                $temp     = $this->getAttamentInfo($md5);
                if (empty($temp)) {
                    $sha1     = hash_file('sha1', $fileInfo->pathName);
                    $uniqueId = $this->algo == 'md5' ? $md5 : $sha1;
                    $saveName = $uniqueId.'.'.$fileInfo->extention;
                    $savePath = $dirname.'/'.$saveName;
                    $url      = $this->config['domain'].'/'.$savePath;

                    list($image_with,$image_height,$mime_type) = $this->file($fileInfo->pathName);
                    if (!$mime_type) $mime_type = $fileInfo->mimeType;

                    $temp = [
                        'origin_name' => $fileInfo->originName,
                        'name'        => $saveName,
                        'save_path'   => $savePath,
                        'url'         => $url,
                        'mime'        => $mime_type,
                        'extension'   => $fileInfo->extention,
                        'size'        => $fileInfo->size,
                        'md5'         => $md5,
                        'sha1'        => $sha1,
                        'driver'      => 'qos',
                        'width'       => $image_with,
                        'height'      => $image_height
                    ];
                    array_push($saveData, $temp);
                    list($ret, $err) = $this->getInstance()->putFile($this->getUploadToken(), $savePath, $fileInfo->pathName);
                    if (!empty($err)) throw new StorageException(json_encode($err));
                }
                array_push($result, $temp);
            }
        } catch (StorageException $e) {
            throw new StorageException($e->getMessage(),$e->getLine());
        }

        # 保存数据
        $this->saveAttament($saveData);
        return $result;
    }


    
    /**
     * @param string $file_path
     * @return array
     * @throws \Exception
     */
    public function uploadServerFile(string $file_path): array
    {
        $file = new \SplFileInfo($file_path);
        if (!$file->isFile()) {
            throw new StorageException('不是一个有效的文件');
        }

        $uniqueId = hash_file($this->algo, $file->getPathname());
        $object = $this->config['dirname'].$this->dirSeparator.$uniqueId.'.'.$file->getExtension();

        $result = [
            'origin_name' => $file->getRealPath(),
            'save_path' => $object,
            'url' => $this->config['domain'].$this->dirSeparator.$object,
            'unique_id' => $uniqueId,
            'size' => $file->getSize(),
            'extension' => $file->getExtension(),
        ];

        list($ret, $err) = $this->getInstance()->putFile($this->getUploadToken(), $object, $file->getPathname());
        if (!empty($err)) {
            throw new StorageException((string) $err);
        }

        return $result;
    }

    /**
     * 上传Base64.
     */
    public function uploadBase64(string $base64, string $extension = 'png'): array
    {
        $base64 = explode(',', $base64);
        $uniqueId = date('YmdHis').uniqid();
        $object = $this->config['dirname'].$this->dirSeparator.$uniqueId.'.'.$extension;

        list($ret, $err) = $this->getInstance()->put($this->getUploadToken(), $object, base64_decode($base64[1]));
        if (!empty($err)) {
            throw new StorageException((string) $err);
        }

        $imgLen = strlen($base64['1']);
        $fileSize = $imgLen - ($imgLen / 8) * 2;

        return [
            'save_path' => $object,
            'url' => $this->config['domain'].$this->dirSeparator.$object,
            'unique_id' => $uniqueId,
            'size' => $fileSize,
            'extension' => $extension,
        ];
    }
}
